﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Hosting;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using NBrightCore.TemplateEngine;
using NBrightCore.common;
using NBrightCore.render;
using NBrightDNN;

namespace DotNetNuke.Modules.NBrightEspace.Components
{
    public static class EspaceFunctions
    {

        public const string FileUploadDir = "fileuploads";

        public static int GetClientID(int PortalId)
        {
            var cookieValue = Cookie.GetCookieValue(PortalId, "Espace", "ClientID");
            if (Utils.IsNumeric(cookieValue))
            {
                return Convert.ToInt32(cookieValue);
            }
            return -1;
        }

        public static void SetClientID(int PortalID, int ClientID)
        {
            Cookie.SetCookieValue(PortalID, "Espace", "ClientID", Convert.ToString(ClientID));
        }

        public static void RemoveClientID(int PortalID)
        {
            Cookie.SetCookieValue(PortalID, "Espace", "ClientID", "-1");
        }

        //public static object getDetailOrListTemplate(string TypeCode, int ItemId, string ModulePath, string ForcedType = "")
        //{
        //    string TemplateName = null;
        //    string strTempl = null;

        //    if (string.IsNullOrEmpty(ForcedType))
        //    {
        //        if (ItemId >= 0)
        //        {
        //            TemplateName = ModulePath + "Templates/" + TypeCode + "_Detail_" + GetCurrentCulture() + ".html";
        //        }
        //        else
        //        {
        //            TemplateName = ModulePath + "Templates/" + TypeCode + "_List_" + GetCurrentCulture() + ".html";
        //        }
        //    }
        //    else
        //    {
        //        TemplateName = ModulePath + "Templates/" + TypeCode + "_" + ForcedType + "_" + GetCurrentCulture() + ".html";
        //    }

        //    strTempl = Hosting.HostingEnvironment.MapPath(TemplateName);

        //    if (!File.Exists(strTempl))
        //    {
        //        strTempl = Strings.Replace(strTempl, "_" + GetCurrentCulture() + ".html", ".html");
        //    }

        //    if (File.Exists(strTempl))
        //    {
        //        return GenCommon.GetFileContents(strTempl);
        //    }
        //    else
        //    {
        //        return "---- NO TEMPLATE FOUND ---- [" + TemplateName + "]";
        //    }
        //}

        public static void DeleteItemRecord(int ItemId, DotNetNuke.Entities.Portals.PortalSettings PortalSettings)
        {
            if (ItemId > 0)
            {
                var objEspaces = new EspaceController();
                var objInfo = objEspaces.Get(ItemId);
                if ((objInfo != null))
                {
                    //delete any upload files that are associated with this record.
                    GenXmlFunctions.DeleteAllUploadedFiles(objInfo.XMLData, PortalSettings.HomeDirectoryMapPath + FileUploadDir);
                }
                //delete record.
                objEspaces.Delete(ItemId);
            }
        }

        public static void CancelLock(int ItemId, Repeater dlDetails, DotNetNuke.Entities.Users.UserInfo UserInfo)
        {
            if (GenXmlFunctions.GetHiddenField(dlDetails, "lockedby").StartsWith(UserInfo.Username + " on"))
            {
                var objCtrl = new EspaceController();
                var objInfo = objCtrl.Get(ItemId);
                if ((objInfo != null))
                {
                    ReleaseLock(objInfo, UserInfo);
                    objCtrl.Update(objInfo);
                }
            }
        }

        public static void SetLock(NBrightInfo objInfo, DotNetNuke.Entities.Users.UserInfo UserInfo)
        {
            var objCtrl = new EspaceController();
            var xmlDoc = new XmlDataDocument();

            if (!string.IsNullOrEmpty(objInfo.XMLData))
            {
                xmlDoc.LoadXml(objInfo.XMLData);

                var xmlNod = xmlDoc.SelectSingleNode("genxml/hidden/lockedby");
                if ((xmlNod != null))
                {
                    if (string.IsNullOrEmpty(xmlNod.InnerXml))
                    {
                        GenXmlFunctions.ReplaceXmlNode(xmlDoc, "genxml/hidden/lockedby", UserInfo.Username + " on " + Convert.ToString(DateTime.Now));
                        GenXmlFunctions.ReplaceXmlNode(xmlDoc, "genxml/hidden/htmldisplaylockedby", "", false);
                        objInfo.XMLData = xmlDoc.OuterXml;
                        objCtrl.Update(objInfo);
                    }
                    else
                    {
                        if (!xmlNod.InnerText.StartsWith(UserInfo.Username + " on"))
                        {
                            GenXmlFunctions.ReplaceXmlNode(xmlDoc, "genxml/hidden/htmldisplaylockedby", "<div class=\"Espace_LockDiv\">Locked by " + xmlNod.InnerText + "</div>", false);
                            objInfo.XMLData = xmlDoc.OuterXml;
                        }
                    }
                }
            }

        }

        public static void ReleaseLock(NBrightInfo objInfo, DotNetNuke.Entities.Users.UserInfo UserInfo, bool ForceRelease = false)
        {
            var objCtrl = new EspaceController();
            var xmlDoc = new XmlDataDocument();

            xmlDoc.LoadXml(objInfo.XMLData);

            var xmlNod = xmlDoc.SelectSingleNode("genxml/hidden/lockedby");
            if ((xmlNod != null))
            {
                if (xmlNod.InnerText.StartsWith(UserInfo.Username + " on") | ForceRelease)
                {
                    GenXmlFunctions.ReplaceXmlNode(xmlDoc, "genxml/hidden/lockedby", "");
                    GenXmlFunctions.ReplaceXmlNode(xmlDoc, "genxml/hidden/htmldisplaylockedby", "", false);
                    objInfo.XMLData = xmlDoc.OuterXml;
                }
            }

        }

        public static bool IsItemLocked(Repeater rpDetails)
        {
            if (!string.IsNullOrEmpty(GenXmlFunctions.GetHiddenField(rpDetails, "htmldisplaylockedby")))
            {
                return true;
            }
            return false;
        }

        public static void SetUpdateMsgIfLocked(Repeater rpDetails, string cmdCtrlName, string LockMsg, DotNetNuke.Entities.Users.UserInfo UserInfo)
        {
            if (IsItemLocked(rpDetails))
            {
                if (!GenXmlFunctions.GetHiddenField(rpDetails, "htmldisplaylockedby").StartsWith(UserInfo.Username + " on"))
                {
                    if ((rpDetails.Items[0].FindControl(cmdCtrlName) != null))
                    {
                        ((LinkButton) rpDetails.Items[0].FindControl(cmdCtrlName)).Attributes.Add("onClick", "javascript:return confirm('" + LockMsg + "');");
                    }
                }
            }
        }

        public static void UpdateClientSelectedXML(int ClientID, int ItemID)
        {
            var objCtrl = new EspaceController();
            var xmlDoc = new XmlDataDocument();
            var xmlCDoc = new XmlDataDocument();

            var objCInfo = objCtrl.Get(ClientID);
            var objInfo = objCtrl.Get(ItemID);

            if (((objInfo != null)) & ((objCInfo != null)))
            {
                xmlDoc.LoadXml(objInfo.XMLData);
                xmlCDoc.LoadXml(objCInfo.XMLData);

                GenXmlFunctions.MergeXmlNodeText(xmlDoc, xmlCDoc, "genxml/textbox/txtclientref");
                GenXmlFunctions.MergeXmlNodeText(xmlDoc, xmlCDoc, "genxml/textbox/txtusername");
                GenXmlFunctions.MergeXmlNodeText(xmlDoc, xmlCDoc, "genxml/textbox/txtclientname");
                GenXmlFunctions.MergeXmlNodeText(xmlDoc, xmlCDoc, "genxml/textbox/txtcompanyname");
                GenXmlFunctions.MergeXmlNodeText(xmlDoc, xmlCDoc, "genxml/textbox/txtpersonalemail");
                GenXmlFunctions.MergeXmlNodeText(xmlDoc, xmlCDoc, "genxml/hidden/clientid", "genxml/hidden/itemid");

                GenXmlFunctions.MergeXmlNodeText(xmlDoc, xmlCDoc, "genxml/textbox/txtclientadd1");
                GenXmlFunctions.MergeXmlNodeText(xmlDoc, xmlCDoc, "genxml/textbox/txtclientadd2");
                GenXmlFunctions.MergeXmlNodeText(xmlDoc, xmlCDoc, "genxml/textbox/txtclientadd3");
                GenXmlFunctions.MergeXmlNodeText(xmlDoc, xmlCDoc, "genxml/textbox/txtclientpc");

                objInfo.XMLData = xmlDoc.OuterXml;

                objCtrl.Update(objInfo);
            }
        }

        public static void UpdateUserSelectedXML(int Portalid, int UserID, int ItemID)
        {
            var objCtrl = new EspaceController();
            var xmlDoc = new XmlDataDocument();

            var objU = DotNetNuke.Entities.Users.UserController.GetUser(Portalid, UserID, false);
            var objInfo = objCtrl.Get(ItemID);

            if (((objInfo != null)) & ((objU != null)))
            {
                xmlDoc.LoadXml(objInfo.XMLData);

                GenXmlFunctions.ReplaceXmlNode(xmlDoc, "genxml/textbox/txtclientname", objU.DisplayName);

                GenXmlFunctions.ReplaceXmlNode(xmlDoc, "genxml/textbox/txtclientadd1", objU.Profile.Unit);
                GenXmlFunctions.ReplaceXmlNode(xmlDoc, "genxml/textbox/txtclientadd2", objU.Profile.Street);
                GenXmlFunctions.ReplaceXmlNode(xmlDoc, "genxml/textbox/txtclientpc", objU.Profile.PostalCode);
                GenXmlFunctions.ReplaceXmlNode(xmlDoc, "genxml/textbox/txtclientadd3", objU.Profile.City);

                GenXmlFunctions.ReplaceXmlNode(xmlDoc, "genxml/hidden/userid", Convert.ToString(UserID));
                GenXmlFunctions.ReplaceXmlNode(xmlDoc, "genxml/hidden/clientid", Convert.ToString(UserID));

                objInfo.XMLData = xmlDoc.OuterXml;

                objCtrl.Update(objInfo);
            }
        }

        //public static ArrayList calculatePayments(System.DateTime FirstPayDate, double TotalHT, double TotalTax, double PrePaid = 0, DateInterval DInterval = DateInterval.Month, int NumPayments = 12, bool RemovePrePaid = true)
        //{
        //    EspacePayment objInfo = default(EspacePayment);
        //    ArrayList aryList = new ArrayList();

        //    for (int lp = 1; lp <= NumPayments; lp++) {
        //        objInfo = new EspacePayment();
        //        objInfo.PaymentNum = lp;
        //        objInfo.DateDue = DateAdd(DInterval, (lp - 1), FirstPayDate);
        //        objInfo.HT = Math.Round(TotalHT / NumPayments, 2);
        //        objInfo.Tax = Math.Round(TotalTax / NumPayments, 2);
        //        objInfo.Due = Math.Round(objInfo.HT + objInfo.Tax, 2);
        //        aryList.Add(objInfo);
        //    }

        //    //change first payment to pickup diff in rounding
        //    ((EspacePayment)aryList.Item(0)).HT += Math.Round(TotalHT - (Math.Round(TotalHT / NumPayments, 2) * NumPayments), 2);
        //    ((EspacePayment)aryList.Item(0)).Tax += Math.Round(TotalTax - (Math.Round(TotalTax / NumPayments, 2) * NumPayments), 2);
        //    ((EspacePayment)aryList.Item(0)).Due = Math.Round(((EspacePayment)aryList.Item(0)).HT + ((EspacePayment)aryList.Item(0)).Tax, 2);

        //    //remove any prepaid amount from payments
        //    if (RemovePrePaid) {
        //        //DON'T REMOVE PREPAID ON INSTALLMENTS, SO IT CAN BE ALLOCATED MANUALLY AS A PAYMENT.
        //        if (PrePaid > 0) {
        //            foreach ( objInfo in aryList) {
        //                if (PrePaid > 0) {
        //                    if (PrePaid >= objInfo.Due) {
        //                        objInfo.PrePaid = Math.Round(objInfo.Due, 2);
        //                        objInfo.Due = 0;
        //                        PrePaid = Math.Round(PrePaid - objInfo.PrePaid, 2);
        //                    } else {
        //                        objInfo.PrePaid = Math.Round(PrePaid, 2);
        //                        objInfo.Due = Math.Round(objInfo.Due - PrePaid, 2);
        //                        PrePaid = 0;
        //                    }
        //                } else {
        //                    break; // TODO: might not be correct. Was : Exit For
        //                }
        //            }
        //        }
        //    }

        //    return aryList;
        //}

        public static void DownloadFileLink(Repeater rpGenXML, string FieldID, System.Web.HttpResponse Response, int RowIndex = 0)
        {
            string FLink = null;
            FLink = GenXmlFunctions.GetField(rpGenXML, FieldID, RowIndex);
            if (!string.IsNullOrEmpty(FLink))
            {
                FLink = HostingEnvironment.MapPath(FLink);
                if (File.Exists(FLink))
                {
                    Utils.ForceDocDownload(FLink, Path.GetFileName(FLink), Response);
                }
            }
        }

        public static string ReplaceUrlValue(string url, string parameter, string newValue)
        {
            if (string.IsNullOrEmpty(newValue))
            {
                return Regex.Replace(url, string.Format("({0}=.*(?=&))", parameter), "", RegexOptions.IgnoreCase);
            }
            else
            {
                return Regex.Replace(url, string.Format("({0}=.*(?=&))", parameter), parameter + "=" + newValue, RegexOptions.IgnoreCase);
            }
        }

        public static string NavigateUrlReplace(HttpRequest Request, DotNetNuke.Entities.Portals.PortalSettings PortalSettings, params string[] AdditionalParameters)
        {
            string strURL = null;
            Hashtable hParamTable = new Hashtable();
            string[] p = null;
            string[] appurl = null;
            string[] absurl = null;

            appurl = DotNetNuke.Common.Globals.ApplicationURL().Split('?');
            absurl = Request.Url.AbsoluteUri.Split('?');

            strURL = appurl[0] + "?" + absurl[1];

            if ((AdditionalParameters != null))
            {
                //put into hastable
                foreach (string parameter in AdditionalParameters)
                {
                    if (!string.IsNullOrEmpty(parameter))
                    {
                        p = parameter.Split('=');
                        if (p.GetUpperBound(0) == 1)
                        {
                            hParamTable.Add(p[0], p[1]);
                        }
                    }
                }

                //replace existing params
                foreach (DictionaryEntry li in hParamTable)
                {
                    strURL = ReplaceUrlValue(strURL, Convert.ToString(li.Key), Convert.ToString(li.Value));
                }

                //add new params
                foreach (DictionaryEntry li in hParamTable)
                {
                    if (!strURL.Contains("&" + Convert.ToString(li.Key)))
                    {
                        if (!string.IsNullOrEmpty(Convert.ToString(li.Value)))
                        {
                            strURL += "&" + Convert.ToString(li.Key) + "=" + Convert.ToString(li.Value);
                        }
                    }
                }

            }

            if (DotNetNuke.Entities.Host.HostSettings.GetHostSetting("UseFriendlyUrls") == "Y")
            {
                return DotNetNuke.Common.Globals.FriendlyUrl(null, strURL, PortalSettings);
            }
            else
            {
                return DotNetNuke.Common.Globals.ResolveUrl(strURL);
            }

        }

        public static decimal CalcNet(string VatRate, string GrossAmt)
        {
            if (!string.IsNullOrEmpty(VatRate) & !string.IsNullOrEmpty(GrossAmt))
            {
                try
                {
                    return Math.Round(((Convert.ToDecimal(GrossAmt))/(100 + Convert.ToDecimal(VatRate)))*100, 2);
                }
                catch (Exception ex)
                {
                    return 0;
                }
            }
            else
            {
                return 0;
            }
        }

        public static double CalcGross(double VatRate, double NetAmt)
        {
            if (VatRate > 0)
            {
                try
                {
                    return Math.Round((Convert.ToDouble(NetAmt))*((Convert.ToDouble(VatRate)/100) + 1), 2);
                }
                catch (Exception ex)
                {
                    return 0;
                }
            }
            else
            {
                return NetAmt;
            }
        }

        public static double CalcVATNet(double VatRate, double NetAmt)
        {
            if (VatRate > 0 & NetAmt > 0)
            {
                try
                {
                    return Math.Round((Convert.ToDouble(NetAmt)/100)*Convert.ToDouble(VatRate), 2);
                }
                catch (Exception ex)
                {
                    return 0;
                }
            }
            else
            {
                return 0;
            }
        }

        public static double CalcVATGross(double VatRate, double GrossAmt)
        {
            bool blnInvertMinus = false;
            if (GrossAmt < 0)
            {
                blnInvertMinus = true;
                GrossAmt = GrossAmt*-1;
            }
            if (VatRate > 0 & GrossAmt > 0)
            {
                try
                {
                    double rtnAmt = 0;
                    rtnAmt = Math.Round((Convert.ToDouble(GrossAmt)/(Convert.ToDouble(VatRate) + 100))*Convert.ToDouble(VatRate), 2);
                    if (blnInvertMinus)
                    {
                        rtnAmt = rtnAmt*-1;
                    }
                    return rtnAmt;
                }
                catch (Exception ex)
                {
                    return 0;
                }
            }
            else
            {
                return 0;
            }
        }

        public static void CreatePDF(string xmlData, string xslFilePath, string OutputFilePath)
        {
            Pdfizer.HtmlToPdfConverter pdfiz = new Pdfizer.HtmlToPdfConverter();
            System.IO.Stream ostream = new System.IO.FileStream(OutputFilePath, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None);
            string html = XslUtils.XslTrans(xmlData, xslFilePath);

            pdfiz.Open(ostream);
            pdfiz.Run(html);
            pdfiz.Close();

        }

        public static string GetReportHtml(string repItemId)
        {
            var dataGridHtml = "";
            if (Utils.IsNumeric(repItemId))
            {
                var objCtrl = new NBrightEspace.Components.EspaceController();
                var objRinfo = objCtrl.Get(Convert.ToInt32(repItemId));
                if ((objRinfo != null))
                {
                    var dgResults = new System.Web.UI.WebControls.DataGrid();

                    var sqlCmd = objRinfo.GetXmlProperty("genxml/textbox/txtsql");
                    if (!string.IsNullOrEmpty(sqlCmd))
                    {

                        var repIDataReader = objCtrl.ExecuteSql(sqlCmd);

                        dgResults.DataSource = repIDataReader;
                        dgResults.DataBind();


                        //Get the rendered HTML
                        var sb = new StringBuilder();
                        var sw = new StringWriter(sb);
                        var htmlTw = new HtmlTextWriter(sw);

                        dgResults.GridLines = GridLines.None;
                        dgResults.Width = System.Web.UI.WebControls.Unit.Percentage(100);
                        dgResults.HeaderStyle.CssClass = "NBright_HeaderStyle";
                        dgResults.FooterStyle.CssClass = "NBright_FooterStyle";
                        dgResults.EditItemStyle.CssClass = "NBright_EditItemStyle";
                        dgResults.SelectedItemStyle.CssClass = "NBright_SelectedItemStyle";
                        dgResults.AlternatingItemStyle.CssClass = "NBright_AlternatingItemStyle";
                        dgResults.ItemStyle.CssClass = "NBright_ItemStyle";
                        dgResults.AllowPaging = false;

                        dgResults.RenderControl(htmlTw);

                        dataGridHtml = sb.ToString();

                    }
                }
            }
            return dataGridHtml;
        }

        public static string GetReportCsv(string repItemId)
        {
            var strOut = "";
            if (Utils.IsNumeric(repItemId))
            {
                var objCtrl = new NBrightEspace.Components.EspaceController();
                var objRinfo = objCtrl.Get(Convert.ToInt32(repItemId));
                if ((objRinfo != null))
                {
                    var dgResults = new System.Web.UI.WebControls.DataGrid();

                    var sqlCmd = objRinfo.GetXmlProperty("genxml/textbox/txtsql");
                    if (!string.IsNullOrEmpty(sqlCmd))
                    {

                        var dr = objCtrl.ExecuteSql(sqlCmd);
                        //Add Header          
                        for (int count = 0; count < dr.FieldCount; count++)
                        {
                            if (dr.GetName(count) != null)
                                strOut += dr.GetName(count);
                            if (count < dr.FieldCount - 1)
                            {
                                strOut += ";";
                            }
                        }
                        strOut += "\n";

                        while (dr.Read())
                        {
                            for (int col = 0; col < dr.FieldCount - 1; col++)
                            {
                                if (!dr.IsDBNull(col))
                                    strOut += dr.GetValue(col).ToString().Replace(";", " ");
                                strOut += ";";
                            }
                            if (!dr.IsDBNull(dr.FieldCount - 1))
                                strOut += dr.GetValue(dr.FieldCount - 1).ToString().Replace(";", " ");
                            strOut += "\n";
                        }

                        dr.Dispose();
                    }
                }
            }
            return strOut;
        }

        /// <summary>
        /// Add up all project time records and update the project totalhours
        /// </summary>
        public static void UpdateProjectTotalTime(int projectid)
        {
            var oEspaceCtrl = new EspaceController();
            var obj = oEspaceCtrl.Get(projectid);
            if ((obj != null))
            {
                var strFilter = " and ([xmlData].value('(genxml/hidden/projectid)[1]', 'nvarchar(10)') = '" + projectid.ToString("") + "') ";
                double total = 0;
                var l = oEspaceCtrl.GetList(-1, -1, "PROJTIME", strFilter);
                foreach (var objL in l)
                {
                    total += objL.GetXmlPropertyDouble("genxml/textbox/txthours");
                }
                obj.SetXmlProperty("genxml/hidden/totalhours", total.ToString(CultureInfo.InvariantCulture));


                //calc the Allocated Hours
                var hourlyRate = obj.GetXmlPropertyDouble("genxml/textbox/txthourlyrate");
                obj.SetXmlProperty("genxml/hidden/hidallocatedhours", "0");
                var invAmt1 = obj.GetXmlPropertyDouble("genxml/textbox/txtinvamt");
                if (invAmt1 > 0 & hourlyRate > 0)
                {
                    var allocHours = invAmt1 / hourlyRate;
                    obj.SetXmlPropertyDouble("genxml/hidden/hidallocatedhours", allocHours);
               }

                //calc the hourly rate
                if (total > 0)
                {
                    var invAmt = obj.GetXmlPropertyDouble("genxml/textbox/txtinvamt");
                    hourlyRate = invAmt/total;
                    obj.SetXmlPropertyDouble("genxml/hidden/hourlyrate", hourlyRate);
                }
                else
                {
                    obj.SetXmlProperty("genxml/hidden/hourlyrate", "0");
                }

                oEspaceCtrl.Update(obj);
            }
        }

        /// <summary>
        /// Use the setting to get the template system getter control.
        /// </summary>
        /// <returns></returns>
        public static TemplateGetter GetTemplateGetter()
        {
            var objCtrl = new EspaceController();
            var objSettings = objCtrl.GetByTypeCode("SETTINGS");

            var controlMapPath = objSettings.GetXmlProperty("genxml/hidden/controlmappath");
            var themeFolder = objSettings.GetXmlProperty("genxml/textbox/txtthemefolder");

            var templCtrl = new NBrightCore.TemplateEngine.TemplateGetter(controlMapPath, controlMapPath, "NBrightTemplates", themeFolder);
            return templCtrl;
        }

    }
}